package elements

import (
	"yizhuoyan/go-study/pdfgo/handyio"
	"yizhuoyan/go-study/pdfgo/raw/objects/basicobject"
)

var trailerKeywordBytes = []byte("trailer")

type TrailerElement struct {
	*basicobject.Dictionary
	size     *basicobject.Integer                 `validate:"required" #:"The total number of entryList in the file’s cross-reference table"`
	root     *basicobject.IndirectObjectReference `validate:"required" #:"Document Catalog"`
	prev     *basicobject.Integer                 `validate:"omitempty" #:"The byte offset from the beginning of the file to the beginning of the previous cross-reference section"`
	Info     *basicobject.IndirectObjectReference `validate:"omitempty" #:"The document’s information"`
	Encrypt  *basicobject.Dictionary              `validate:"omitempty" #:"Required if document is encrypted"`
	ID       *basicobject.Array                   `validate:"omitempty" #:"2 byte-strings"`
	Previous *TrailerElement
}

// (required)The total number of entryList in the file’s cross-reference table
func (this *TrailerElement) RequiredFieldSize() *basicobject.Integer {
	return this.MustGetInteger("/Size")
}

// (required)Document Catalog
func (this *TrailerElement) RequiredFieldRoot() *basicobject.IndirectObjectReference {
	return this.MustGetIndirectObjectReference("/Root")
}
func (this *TrailerElement) FieldPrev() *basicobject.Integer {
	return this.MustGetInteger("/Prev")
}

func (this *TrailerElement) Write(w handyio.PdfRawWriter) error {
	w.WriteBytes(trailerKeywordBytes)
	w.WriteEndOfLine()
	var dictionary = new(basicobject.Dictionary)
	dictionary.Put("/Size", this.size)
	dictionary.Put("/Root", this.root)
	if this.prev != nil {
		dictionary.Put("/Prev", this.prev)
	}
	if this.Info != nil {
		dictionary.Put("/Info", this.Info)
	}
	if this.Encrypt != nil {
		dictionary.Put("/Encrypt", this.Encrypt)
	}
	if this.ID != nil {
		dictionary.Put("/ID", this.ID)
	}
	return dictionary.Serialize(w)

}

func (this *TrailerElement) Read(r handyio.PdfRawReader) error {
	if !r.NextBytesEquals(trailerKeywordBytes) {
		return r.NotSupport("无trailer")
	}
	startAt := r.IndexCurrent()
	r.SkipNextWhiteSpaces()
	var dictionary = new(basicobject.Dictionary)
	if err := dictionary.UnSerialize(r); err != nil {
		_ = r.IndexMoveTo(startAt)
		return err
	}
	if !dictionary.HasKey("/Root") {
		return r.NotSupport("无/Root")
	}
	if !dictionary.HasKey("/Size") {
		return r.NotSupport("无/Size")
	}
	this.Dictionary = dictionary
	r.SkipNextWhiteSpaces()
	return nil
}
